#pragma once
#include <poll.h>
#include<vector>
#include "socket.hpp"
#include"Log.hpp"

#define Size 10
int defaultfd=-1;

class PollServer
{
public:
    PollServer(uint16_t port)
        : port_(port)
        ,pfdnum(0)
    {
        for (int i = 0; i < Size; i++)
        {
            pfds[i].fd =defaultfd;
            pfds[i].events=0;
            pfds[i].revents=0;
            //memset(&pfds[i],0,sizeof(pfds[i]));
        }
    }

    void init()
    {
        listen_socket.Socket();
        listen_socket.Bind(port_);
        listen_socket.Listen();
        // struct pollfd*newfd=new pollfd();
        // newfd.fd=listen_socket.Listenfd();
        // newfd.events= POLLIN; | POLLWRNORM;
        // struct pollfd listenfd;
        // listenfd.fd=listen_socket.Listenfd();
        // listenfd.events = POLLIN; | POLLWRNORM;
        // pfds.push_back(listenfd);
        pfds[0].fd = listen_socket.Listenfd();
        pfds[0].events = POLLIN;//|POLLOUT;
        pfdnum++;
    }

    // 事件派发器
    void dispatch(int n)
    {
        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < Size; i++)
            {
                if (pfds[i].fd >0)
                {
                    char buffer[1024]="\0";
                    //std::cout<<"i"<<std::endl;
                    if (pfds[i].revents&POLLIN)
                    {
                        //添加新的等待
                        if (pfds[i].fd==listen_socket.Listenfd())
                        {
                            //std::cout<<"g"<<std::endl;
                            //怎么判断是单个连接还是多个连接？
                            for (int g = 0; g < Size; g++)
                            {
                                if (pfds[g].fd ==defaultfd)
                                {
                                    int fd = listen_socket.Accept();
                                    pfds[g].fd = fd;
                                    pfds[g].events =POLLIN;//|POLLOUT;
                                    std::cout<<"get a new accept;fd:"<<fd<<std::endl;
                                    pfds[g].revents&=0<< POLLIN;
                                    pfdnum++;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            std::string message;
                            // char buffer[1024];
                            int n = read(pfds[i].fd, buffer, sizeof(buffer));
                            if (n > 0)
                            {
                                buffer[n-1] = 0;
                                std::cout<< "get a message,fd:"<<pfds[i].fd<<",message:"<<buffer<<std::endl;
                                break;
                            }
                            else if (n==0)
                            {
                                break;
                            }
                            else if(n<0)
                            {
                                lg(Fatal,"read err,errno:%d,str:%s\n",errno,strerror(errno));
                            }
                        }
                    }
                    //为什么客户写事件一直就绪？
                    if (pfds[i].revents&POLLWRNORM)
                    {
                        std::string s;
                        s+="Server#";
                        s+=buffer;
                        if(s!="Server#")
                            write(pfds[i].fd,s.c_str(),s.size());
                        //std::cout<<pfds[i].fd<<" POLLWRNORM OK"<<std::endl;
                        pfds[i].revents&=0<<POLLIN;;
                    }
                }
            }
        }
    }

    void Printfds()
    {
        for(int i=0;i<Size;i++)
        {
            printf("fds[%d],fd:%d,events:%d,revents:%d\n",i,pfds[i].fd,pfds[i].events,pfds[i].revents);
        }
    }

    void start()
    {

        for (;;)
        {
            //
            //std::cout<<11111111111<<std::endl;
            //Printfds();
            //int n = poll(pfds, sizeof(pfds), 3000);
            int n = poll(pfds, pfdnum, 3000);
            //为什么初始化时n=63？
            //pfds是需要关照的个数,而不是数组的大小

            //std::cout<<n<<std::endl;
            // 事件判断处理
            switch (n)
            {
            case 0:
                printf("NOT ready\n");
                continue;
            case -1:
                printf("poll err,errno:%d,str:%s\n", errno, strerror(errno));
            default:
                Printfds();
                dispatch(n);
            }
            sleep(2);
        }
    }

    ~PollServer()
    {
        listen_socket.Close();
    }

private:
    Sock listen_socket;
    uint16_t port_;
    struct pollfd pfds[Size];
    int pfdnum;
    //std::vector<struct pollfd> pfds; 
};